/**
 * Copyright 2009-2010 - YangJiandong(chunquedong)
 * 
 * This file is part of ChunMap project
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
 * 你可以自由复制、传播本项目的下载包文件，但必须保持其完整性。
 * 我们不用对使用中的风险及由此造成的损失承担任何责任。
 * 详细情况请见《ChunMap许可协议》。

 * 想了解更多有关ChunMap的信息，请访问http://code.google.com/p/chunmap/
 */
package chunmap.model.elem;

import chunmap.model.coord.Position;
import chunmap.model.coord.Coordinate2D;
import chunmap.model.coord.Coordinate3D;

/**
 * 向量运算类
 * @author chunquedong
 * 
 */
public class Vector {

	private final Position point;

	public Vector(double x, double y, double z) {
		point = new Coordinate3D(x, y, z);
	}

	public Vector(Position p1, Position p2) {
		double x = p2.getX() - p1.getX();
		double y = p2.getY() - p1.getY();

		double z = 0;
		if (p1.is3D() && p2.is3D())
			z = p2.getZ() - p1.getZ();

		point = new Coordinate3D(x, y, z);
	}

	public double getX() {
		return point.getX();
	}

	public double getY() {
		return point.getY();
	}

	public double getZ() {
		return point.getZ();
	}

	/**
	 * 平行四边形代数面积
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public double get2DCrossProduct(Vector v2) {
		Vector v1 = this;
		return v1.getX() * v2.getY() - v2.getX() * v1.getY();// a1b2-a2b1
	}

	@Override
	public String toString() {
		return "Vector(" + point.getX() + " " + point.getY() + ")";
	}

	// ------------------------------------------------------------
	/**
	 * 相加
	 */
	public Vector add(Vector v2) {
		double x = this.getX() + v2.getX();
		double y = this.getY() + v2.getY();
		double z = this.getZ() + v2.getZ();

		return new Vector(x, y, z);
	}

	/**
	 * 数乘
	 * 
	 * @param n
	 * @param v
	 * @return
	 */
	public Vector shuCheng(double n) {
		double x = n * getX();
		double y = n * getY();
		double z = n * getZ();

		return new Vector(x, y, z);
	}

	public double computeAngle(Vector v2) {
		Position p = new Coordinate2D(0, 0);
		Angle angle = new Angle(point, p, v2.point);
		return angle.computeAngle();
	}

	/**
	 * 外积
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public Vector outerMultiply(Vector v2) {
		double x = getY() * v2.getZ() - v2.getY() * getZ();// b1c2-b2c1
		double y = getZ() * v2.getX() - getX() * v2.getZ();// c1a2-a1c2
		double z = getX() * v2.getY() - v2.getX() * getY();// a1b2-a2b1

		return new Vector(x, y, z);
	}

	/**
	 * 内积
	 * 
	 * @param v1
	 * @param v2
	 * @return
	 */
	public double innerMultiply(Vector v2) {
		double x = getX() * v2.getX();
		double y = getY() * v2.getY();
		double z = getZ() * v2.getZ();

		return x + y + z;
	}
}
